#include "memery.h"

//开辟一个静态缓存作为内存池
MemPoolTypedef MemPool @0x10000000;
volatile uint8_t memtest = 1;

/* 2020-3-31 wy
 * 裸机内存池模块
 * 栈数据结构，先申请的后释放
 * 可嵌套层数:BLOCK_NUM
 * 内存池大小:MEM_MAX_SIZE
 * allocbuf 和 freebuf必须成对出现，且最新申请的要最先释放
 * */

void MemPoolInit(void)
{
    //timetest();
    memset((void *)&MemPool,0,sizeof(MemPool));

}

void *Allocbuf(uint32_t size)
{
    void *rc = 0;
    uint16_t i,Addroffset = 0;

    //转换到4字节对齐(向上取整)
    size = ((size + ALIGN_WIDE - 1)/ALIGN_WIDE) * ALIGN_WIDE;

    if(size == 0)
    {
        return rc;
    }

    for(i = 0;i < BLOCK_NUM;i++)
    {
        //如果剩余空间已不够，直接返回0
        if(Addroffset + size > MEM_MAX_SIZE)
        {
            MemPool.isPoolOverFlow = 1;
            return rc;
        }

        if(MemPool.block[i].UseLen == 0)
        {
            MemPool.block[i].UseLen     = size;
            MemPool.block[i].AddrStart  = Addroffset;
            MemPool.block[i].AddrEnd    = Addroffset + size - 1;
            MemPool.UsedBlock++;
            //统计最大申请块数和最大申请空间，用于评估程序运行状态
            if(MemPool.UsedBlock > MemPool.MaxUsedBlock)
            {
                MemPool.MaxUsedBlock = MemPool.UsedBlock;
            }
            if(MemPool.block[i].AddrEnd > MemPool.MaxUsedSize)
            {
                MemPool.MaxUsedSize = MemPool.block[i].AddrEnd + 1;
            }
            break;
        }
        else
        {
            Addroffset += MemPool.block[i].UseLen;
        }
    }

    //如果不大于最大的块个数(最大嵌套个数)
    if(i < BLOCK_NUM)
    {
        rc = (void *)&MemPool.pool[Addroffset];
        memset(rc,0,size);
    }
    return rc;
}

void  Freebuf(void *pbuf)
{
    if(pbuf == 0)
    {
        return;
    }
    //如果释放的内存不是最后一块,即最新申请的
    if(pbuf != ((void *)&MemPool.pool[MemPool.block[MemPool.UsedBlock - 1].AddrStart]))
    {
        memtest = 0;
        ASSERT(1);
        return;
    }
    //释放使用权
    memset((void *)&MemPool.block[MemPool.UsedBlock - 1],0,sizeof(MemBlockTypdef));

    MemPool.UsedBlock--;

}

void MemTest()
{
    uint8_t *test[12];
    int8_t i,j;
    volatile uint16_t alloclen;
    uint16_t k;
    uint16_t temp_alloclen;

    //从嵌套1层到嵌套12层的随机长度的申请、释放
    for(j = 1;j <= 12;j++)
    {

        srand (HAL_GetTick());

        for(i = 0;i < j;i++)
        {
            //HAL_Delay(5);
            alloclen = rand()%1024;
            
            temp_alloclen = alloclen;
            
            test[i] = Mem.malloc(temp_alloclen);
            for(k = 0;k < temp_alloclen;k++)
            {
                *(test[i] + k) = k + 1;
            }
        }

        for(i = j-1;i >= 0;i--)
        {
            //HAL_Delay(5);
            Mem.free(test[i]);
        }
    }

    //嵌套12层,每层申请1-4096个并释放
    for(k = 1;k <= 4096;k++)
    {
        for(j = 0;j < 12;j++)
        {
            test[j] = Mem.malloc(k);
        }

        for(j = 11;j >= 0;j--)
        {
            Mem.free(test[j]);
        }
    }


    //一次性全申请并释放
    test[0] = Mem.malloc(4096);
    for(k = 0;k < 4096;k++)
    {
        *(test[0] + k) = k + 1;
    }
    Mem.free(test[0]);
}

//接口注册
MemPoolIfTypedef Mem = {
    .test   = MemTest,
    .init   = MemPoolInit,
    .malloc = Allocbuf,
    .free   = Freebuf
};